/** 
* All Rights Reserved , Copyright (C) 2022 , 青岛鼎信通讯股份有限公司
* 
* SdProjectOverdueInfoService
* SD项目超期记录表
* 
* 修改纪录
* 2022-02-22 版本：1.0 hudeyong 创建。
* @version 版本：1.0
* @author 作者：hudeyong
* 创建日期：2022-02-22
*/
package com.topscomm.gpm.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.topscomm.gpm.pojo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.topscomm.basic.BasicEntity;
import com.topscomm.cbo.pojo.CboApprovalFlowInsEntity;
import com.topscomm.cbo.service.impl.CboApprovalFlowInsService;
import com.topscomm.cbo.service.impl.CboApprovalNodeInsService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.gpm.pojo.GpmProjectMilepostEntity;
import com.topscomm.gpm.service.IGpmProjectOverdueInfoService;
import com.topscomm.gpm.service.impl.auto.GpmProjectOverdueInfoServiceAuto;

@Service(value = "gpmProjectOverdueInfoService")
@Scope(value = "singleton")
public class GpmProjectOverdueInfoService extends GpmProjectOverdueInfoServiceAuto implements IGpmProjectOverdueInfoService {
	@Autowired
	protected GpmProjectService gpmProjectService;
	@Autowired
	protected GpmProjectMilepostService gpmProjectMilepostService;
	@Autowired
	protected GpmProjectTaskService gpmProjectTaskService;
	@Autowired
	protected CboApprovalNodeInsService cboApprovalNodeInsService;
	@Autowired
	protected CboApprovalFlowInsService cboApprovalFlowInsService;
	@Autowired
	protected GpmWfFormService gpmWfFormService;
	@Autowired
	protected GpmProjectReviewService gpmProjectReviewService;
	
	/**
	 *
	 * @param paraMap
	 * @author hdy
	 * @date 2022-03-24
	 * @description 超期记录
	 * @return void
	 */
	public void saveOverdueInfo() {
		Map<String, Object> paraMap = new HashMap<String, Object>();
		//获取复盘未结束或未复盘项目
		List<Map<String, Object>> projectList = this.queryMap(paraMap, "queryNoReviewList");
		StringBufferProxy sql = new StringBufferProxy();
		for(Map<String, Object> project : projectList) {
			String projectid = ConvertUtil.convertToString(project.get("id"));
			String projectname = ConvertUtil.convertToString(project.get("projectname"));
			String projectcode = ConvertUtil.convertToString(project.get("projectcode"));
			// 查询超期里程碑
			sql.clear();
			sql.appendSingle("PROJECTID = {0} AND ENABLED = 1 AND MILEPOSTSTATE != '1' AND SYSDATE > PLANFINISHTIME + 1",
					projectid);
			List<GpmProjectMilepostEntity> sdMilePostTemplateEntities = gpmProjectMilepostService.queryByWhere(sql.toString());
			List<BasicEntity> list = new ArrayList<>();
			for(GpmProjectMilepostEntity gpmProjectMilepostEntity : sdMilePostTemplateEntities) {
				String milepostid = ConvertUtil.convertToString(gpmProjectMilepostEntity.getId());
				sql.clear();
				sql.appendSingle("OVERDUEID = '{0}' and PROJECTID = '{1}' and OVERDUETYPE = '2'",
						milepostid,projectid);
				List<GpmProjectOverdueInfoEntity> sdProjectOverdueInfoEntities = this.queryByWhere(sql.toString());
				if(sdProjectOverdueInfoEntities.size()==0) {
					GpmProjectOverdueInfoEntity overdueInfoEntity = new GpmProjectOverdueInfoEntity();
					overdueInfoEntity.setProjectid(projectid);
					overdueInfoEntity.setProjectname(projectname);
					overdueInfoEntity.setProjectcode(projectcode);
					overdueInfoEntity.setOverduetype("2");
					overdueInfoEntity.setOverdueid(milepostid);
					overdueInfoEntity.setOverduereason("里程碑超期");
                    overdueInfoEntity.setOverduecontent(gpmProjectMilepostEntity.getMilepostname());
					overdueInfoEntity.setOverdueusercode(gpmProjectMilepostEntity.getResponsiblecode());
					overdueInfoEntity.setOverdueusername(gpmProjectMilepostEntity.getResponsible());
					list.add(overdueInfoEntity);
				}
			}
			this.insertBatch(list);
			// 查询超期任务
			sql.clear();
			sql.appendSingle("PROJECTID = {0} AND ENABLED = 1 AND TASKSTATE  != '2'  AND SYSDATE > ACTUALENDDATE + 1",
					projectid);
			List<GpmProjectTaskEntity> sdProjectTaskEntities = gpmProjectTaskService.queryByWhere(sql.toString());
			list = new ArrayList<>();
			for(GpmProjectTaskEntity gpmProjectTaskEntity : sdProjectTaskEntities) {
				String taskid = ConvertUtil.convertToString(gpmProjectTaskEntity.getId());
				sql.clear();
				sql.appendSingle("OVERDUEID = '{0}' and PROJECTID = '{1}' and OVERDUETYPE = '3'",
						taskid,projectid);
				List<GpmProjectOverdueInfoEntity> sdProjectOverdueInfoEntities = this.queryByWhere(sql.toString());
				if(sdProjectOverdueInfoEntities.size()==0) {
					GpmProjectOverdueInfoEntity overdueInfoEntity = new GpmProjectOverdueInfoEntity();
					overdueInfoEntity.setProjectid(projectid);
					overdueInfoEntity.setProjectname(projectname);
					overdueInfoEntity.setProjectcode(projectcode);
					overdueInfoEntity.setOverduetype("3");
					overdueInfoEntity.setOverdueid(taskid);
					overdueInfoEntity.setOverduereason("任务超期");
                    overdueInfoEntity.setOverduecontent(gpmProjectTaskEntity.getTaskname());
					overdueInfoEntity.setOverdueusercode(gpmProjectTaskEntity.getResponsiblecode());
					overdueInfoEntity.setOverdueusername(gpmProjectTaskEntity.getResponsible());
					list.add(overdueInfoEntity);
				}
			}
			this.insertBatch(list);
			sql.clear();
		}
		//流程超期
		sql.clear();
		//为更加精确,将Sd%分解为SdWfForm%和SdProject%
		sql.appendSingle("(sourcetype like 'GpmWfForm%' or sourcetype like 'GpmProject%') and state != '2' and state != '9' and SYSDATE - startdate > 2 ");
		 List<CboApprovalFlowInsEntity> cboApprovalFlowInsEntities = this.cboApprovalFlowInsService
	                .queryByWhere(sql.toString());
		 if (!cboApprovalFlowInsEntities.isEmpty()) {
	        	// 将审批流实例按照sourcetype分组，减少查询次数
	            Map<String, List<CboApprovalFlowInsEntity>> flowinsListMap = cboApprovalFlowInsEntities.stream()
	                    .collect(Collectors.groupingBy(item -> item.getSourcetype()));
	            // 所有需要更新异常状态的项目code
	            Set<String> projectCodes = new HashSet<>();
	            flowinsListMap.forEach((key, value) -> {
	                // 根据不同的sourcetype查询不同的表获取项目code
	                String sourceids = value.stream().map(map -> ConvertUtil.convertToString(map.getSourceid()))
	                        .collect(Collectors.joining(","));
	                sql.clear();
	                if (GpmWfFormEntity.tableName.equals(key)) {
	                	// 立项及立项变更SdProjectCirculated
	                    sql.appendSingle("SELECT a.id,a.FINALSOURCEID as projectid,b.PROJECTCODE,b.PROJECTNAME,a.SOURCETYPE FROM GpmWfForm a LEFT JOIN GpmPROJECT b ON a.FINALSOURCEID = b.id WHERE a.id in ({0})  ",
	                    		sourceids);
	                } else if (GpmProjectTaskFeedbackEntity.tableName.equals(key)) {
	                    // 任务反馈
	                    sql.appendSingle("SELECT a.id,'GpmProjectTaskFeedback' AS SOURCETYPE,s.ID AS projectid, s.PROJECTCODE AS PROJECTCODE, s.PROJECTNAME FROM GPMProjectTaskFeedback a LEFT JOIN GpmProjectTask b ON a.TASKID = b.id LEFT JOIN GPMPROJECT s ON s.id = b.PROJECTID  WHERE a.id IN ({0})",
	                    		sourceids);
	                } else if (GpmProjectTaskCloseEntity.tableName.equals(key)){
	                	// 任务关闭
	                	sql.appendSingle("SELECT a.id,'GpmProjectTaskClose' AS SOURCETYPE,s.ID AS projectid, s.PROJECTCODE AS PROJECTCODE, s.PROJECTNAME FROM GPMProjectTaskClose a LEFT JOIN GpmProjectTask b ON a.TASKID = b.id LEFT JOIN SDPROJECT s ON s.id = b.PROJECTID  WHERE a.id IN ({0})",
	                    		sourceids);
	                }else {
	                    sql.appendSingle("SELECT a.id, '{0}' as SOURCETYPE, s.ID AS projectid, s.PROJECTCODE AS PROJECTCODE, s.PROJECTNAME  FROM {0} a LEFT JOIN SDPROJECT s ON a.PROJECTID = s.id WHERE a.ID IN ({1})", key, sourceids);
	                }
	                List<Map<String, Object>> maps = this.selectExecute(sql.toString());
	                List<BasicEntity> list = new ArrayList<>();
	                for(Map<String, Object> map : maps) {
	                	String id =ConvertUtil.convertToString(map.get("id"));
	                	String projectid = ConvertUtil.convertToString(map.get("projectid"));
	                	String sourcetype = ConvertUtil.convertToString(map.get("sourcetype"));
	                	String flowname = "";
	                	if("GpmProject".equals(sourcetype)) {
	                		flowname = "立项审批";
	                	} else if("GpmProjectHistory".equals(sourcetype)) {
	                		flowname = "立项变更";
	                	} else {
	                		sql.clear();
	                		sql.appendSingle("SELECT NAME FROM CBOITEMDETAILS WHERE ITEMID = (SELECT id FROM CBOITEMS WHERE code = 'CboApprovalFlowCategory') AND code = '{0}'",
	                				sourcetype);
	                		List<Map<String, Object>> flowmaps = this.selectExecute(sql.toString());
	                		if(flowmaps.size()>0) {
	                			flowname = ConvertUtil.convertToString(flowmaps.get(0).get("name"));
	                		}
	                	}
	                	sql.clear();
	    				sql.appendSingle("OVERDUEID = '{0}' and PROJECTID = '{1}' and OVERDUETYPE = '1'",
	    						id,projectid);
	    				List<GpmProjectOverdueInfoEntity> sdProjectOverdueInfoEntities = this.queryByWhere(sql.toString());
	    				if(sdProjectOverdueInfoEntities.size()==0) {
	    					GpmProjectOverdueInfoEntity overdueInfoEntity = new GpmProjectOverdueInfoEntity();
	    					overdueInfoEntity.setProjectid(projectid);
	    					overdueInfoEntity.setProjectname(ConvertUtil.convertToString(map.get("projectname")));
	    					overdueInfoEntity.setProjectcode(ConvertUtil.convertToString(map.get("projectcode")));
	    					overdueInfoEntity.setOverduetype("1");
	    					overdueInfoEntity.setOverdueid(id);
	    					overdueInfoEntity.setOverduereason(ConvertUtil.convertToString(map.get("sourcetype")));
	    					overdueInfoEntity.setOverduecontent(flowname+"流程超期");
//	    					overdueInfoEntity.setOverduereason(flowname+"流程超期");
//	    					overdueInfoEntity.setOverduecontent(ConvertUtil.convertToString(map.get("sourcetype")));
//	    					overdueInfoEntity.setOverdueusercode(ConvertUtil.convertToString(map.get("sourcetype")));
//	    					overdueInfoEntity.setOverdueusername(ConvertUtil.convertToString(map.get("sourcetype")));
	    					list.add(overdueInfoEntity);
	    				}
	                }
	                this.insertBatch(list);
	            });
	     }
	}
}
	
